package org.opens.config;

import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.CacheWriter;
import com.github.benmanes.caffeine.cache.Caffeine;
import com.github.benmanes.caffeine.cache.RemovalCause;
import lombok.extern.slf4j.Slf4j;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.cache.CacheManager;
import org.springframework.cache.caffeine.CaffeineCacheManager;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;

import java.util.concurrent.TimeUnit;

/**
 * 本地caffeine缓存配置
 *
 * @author zym
 * @Date 2022/6/29 14:24
 */
@Configuration
@ConditionalOnProperty(prefix = "spring.cache",name = "type",havingValue = "caffeine")
@Slf4j
public class CaffeineConfig {

    @Bean
    public Cache<String, Object> caffeineCache() {
        return Caffeine.newBuilder()
                // 设置最后一次写入或访问后经过固定时间过期
                .expireAfterWrite(5, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                // 缓存的最大条数
                .maximumSize(1000)
                .build();
    }

    /**
     * 配置缓存管理器
     *
     * @return 缓存管理器
     */
    @Bean("caffeineCacheManager")
    public CacheManager cacheManager() {
        log.info("使用caffeine作为缓存");
        CaffeineCacheManager cacheManager = new CaffeineCacheManager();
        cacheManager.setCaffeine(Caffeine.newBuilder()
                // 最后一次写入后经过固定时间过期300秒
                .expireAfterWrite(10, TimeUnit.SECONDS)
                // 初始的缓存空间大小
                .initialCapacity(100)
                //cache对缓存写的通知回调
                .writer(new CacheWriter() {
                    @Override
                    public void write(@NonNull Object key, @NonNull Object value) {
                        log.info("key={}, CacheWriter write", key);
                        log.info("value={}, CacheWriter write value", value);
                    }

                    @Override
                    public void delete(@NonNull Object key, @Nullable Object value, @NonNull RemovalCause cause) {
                        log.info("key={}, cause={}, CacheWriter delete", key, cause);
                        log.info("value={}, cause={}, CacheWriter delete value", value, cause);
                    }
                })
                // 缓存的最大条数
                .maximumSize(1000));
        return cacheManager;
    }

}
